package com.sina.shop.service.card;

import com.sina.shop.core.exception.client.DataException;
import com.sina.shop.core.exception.server.CreateException;
import com.sina.shop.core.exception.server.ResourceExistsException;
import com.sina.shop.core.exception.server.UpdateException;
import com.sina.shop.dao.card.CardDao;
import com.sina.shop.domain.card.Card;
import com.sina.shop.service.ShopDataSourceService;
import com.sina.shop.util.Assert;
import com.sina.shop.util.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.sina.shop.service.ServiceConstant.SHOP_TX;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2018-02-06-15:01
 */
@Service("cardService")
public class CardServiceImpl extends ShopDataSourceService implements CardService {

    @Autowired
    @Qualifier("cardDao")
    private CardDao cardDao;

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public List<Card> getCardListByAdminId(Long adminId) {
        return cardDao.getCardListByAdminId(adminId);
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public int deleteCard(Long id) throws DataException, UpdateException {
        Card card = cardDao.get(Card.class, id);
        Assert.assertNotNull(card, "Card[id=%s] not exists", card.getId());

        try {
            return cardDao.deleteCard(id);
        } catch (DataAccessException e) {
            LOG.error(" {} delete Card error.", Card.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public Card getCardById(Long id) {
        return cardDao.get(Card.class, id);
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.READ_COMMITTED)
    public Card saveCard(Card card) throws CreateException, ResourceExistsException, DataException {
        try {

            cardDao.save(card);
            cardDao.flush();
            return card;
        } catch (DataAccessException e) {
            LOG.error("{} save Card error.", Card.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public Card updateCard(Card card) throws UpdateException, DataException {
        Card c = cardDao.get(Card.class, card.getId());
        Assert.assertNotNull(c, "Card[id=%s] not exists", card.getId());

        try {
            c = updateCardFiled(card, c);
            cardDao.flush();

            return c;
        } catch (DataAccessException e) {
            LOG.error("{} update Card error.", Card.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    private Card updateCardFiled(Card oldCard, Card newCard) {


        if (oldCard.getSum() != null) {
            newCard.setSum(oldCard.getSum());
        }

        if (oldCard.getGoods() != null) {
            newCard.setGoods(oldCard.getGoods());
        }

        if (oldCard.getAdmin() != null) {
            newCard.setAdmin(oldCard.getAdmin());
        }
        return newCard;
    }
}
